package com.code.generation.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @ProjectName: codegeneration
 * @Package: com.code.generation.utils
 * @Description:
 * @Author: DongJW
 * @CreateDate: 2020/11/29 11:40
 * @Version: 1.0
 */
public class FileUtils {

    private static Map<String,List<File>> filesCache = new ConcurrentHashMap<>();

    /**
     * 使用递归找出某目录("C:\\JavaProducts")下的所有子目录以及子文件
     * @param dir 文件路径
     * @param fileNames 文件列表
     * @return
     */
    public static List<File> getAllFiles(File dir, List<File> fileNames) throws Exception {

        String filesKey = dir.getPath();
        //先从缓存中读取，不用重复获取
        if (filesCache.containsKey(filesKey)){
            return filesCache.get(filesKey);
        }

        // 判断是否存在目录
        if (!dir.exists() || !dir.isDirectory()) {
            throw new Exception("["+dir.getPath()+"] 目录不存在!");
        }
        // 读取目录下的所有目录文件信息
        String[] files = dir.list();
        // 循环，添加文件名或回调自身
        for (int i = 0; i < files.length; i++) {
            File file = new File(dir, files[i]);
            // 如果文件
            if (file.isFile()) {
                // 添加文件全路径名
                fileNames.add(new File(dir + File.separator + file.getName()));
            } else {
                // 如果是目录
                // 回调自身继续查询
                getAllFiles(file, fileNames);
            }
        }
        //放入缓存
        filesCache.put(filesKey,fileNames);
        return fileNames;
    }

    public static File  createFile(String path,String filename) throws IOException {
        File file=new File(path+File.separatorChar+filename);
        File fileParent = file.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();// 能创建多级目录
        }
        if(!file.exists()) {
            file.createNewFile();
        }
        return file;
    }

    public static void copyFolder(String oldPath, String newPath) {
        try {
            // 如果文件夹不存在，则建立新文件夹
            (new File(newPath)).mkdirs();
            //读取整个文件夹的内容到file字符串数组，下面设置一个游标i，不停地向下移开始读这个数组
            File filelist = new File(oldPath);
            String[] file = filelist.list();
            //要注意，这个temp仅仅是一个临时文件指针
            //整个程序并没有创建临时文件
            File temp;
            for (String s : file) {
                //如果oldPath以路径分隔符/或者\结尾，那么则oldPath/文件名就可以了
                //否则要自己oldPath后面补个路径分隔符再加文件名
                //谁知道你传递过来的参数是f:/a还是f:/a/啊？
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + s);
                } else {
                    temp = new File(oldPath + File.separator + s);
                }

                //如果游标遇到文件
                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);

                    File newTemp;
                    if (newPath.endsWith(File.separator)) {
                        newTemp = new File(newPath + s);
                    } else {
                        newTemp = new File(newPath + File.separator + s);
                    }

                    FileOutputStream output = new FileOutputStream(newTemp);
                    byte[] bufferarray = new byte[1024 * 64];
                    int prereadlength;
                    while ((prereadlength = input.read(bufferarray)) != -1) {
                        output.write(bufferarray, 0, prereadlength);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                //如果游标遇到文件夹
                if (temp.isDirectory()) {
                    copyFolder(oldPath + File.separator + s, newPath + File.separator + s);
                }
            }
        } catch (Exception e) {
            System.out.println("复制整个文件夹内容操作出错"+e.getMessage());
        }
    }

}
